﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners;
using System.Diagnostics;
using System.IO;
using System.Configuration;
using System.Reflection;
using NLog;
using NLog.Config;
using NLog.LayoutRenderers;

namespace LogManager
{
    public static class Logger
    {
        #region 旧版Logger
        //private static Dictionary<string, string> LogArray = new Dictionary<string, string>();
        //private static bool m_bLogFlag = true;//是否记录日志
        //private static bool CheckLogChanged(string strModuleName)
        //{
        //    try
        //    {
        //        string logByDay = ConfigurationManager.AppSettings[strModuleName + "LogByDay"];
        //        if (logByDay == null)
        //            logByDay = "1";

        //        #region//获取日志文件名称到strName
        //        string LogName = ConfigurationManager.AppSettings[strModuleName + "LogName"];
        //        if (LogName == null)
        //            LogName = strModuleName;
        //        string strMonth = System.DateTime.Now.ToString("yyyy-MM");
        //        string strTime = System.DateTime.Now.ToString("yyyy-MM-dd");
        //        string path = System.AppDomain.CurrentDomain.BaseDirectory;
                    
        //        if (Directory.Exists(path + "Log") == false)
        //            Directory.CreateDirectory(path + "Log");
        //        if (Directory.Exists(path + "Log\\" + strMonth) == false)
        //            Directory.CreateDirectory(path + "Log\\" + strMonth);//按月归并日志
        //        string strName = path + "Log\\" + strMonth + "\\" + LogName;
        //        if (logByDay == "1")
        //            strName += strTime + ".log";
        //        else
        //            strName = path + "Log\\"+LogName+".log";
        //        #endregion

        //        bool bRecorded = LogArray.ContainsKey(strModuleName);
        //        if (bRecorded == false)
        //        {
        //            LogArray.Add(strModuleName, strName);
        //            return true;
        //        }
        //        else
        //        {
        //            if (LogArray[strModuleName] == strName)//还是当天日志，日志文件名称不需要变更
        //                return false;
        //            else
        //            {
        //                LogArray[strModuleName] = strName;
        //                return true;
        //            }
        //        }
        //    }
        //    catch (Exception)
        //    {
        //    }
        //    return true;
        //}

        //#region//日志输出
        //public static void Write(string ModuleName, object msg,IDictionary<string,object> prop)
        //{
        //    if (m_bLogFlag == false)
        //        return;
        //    bool bChanged = CheckLogChanged(ModuleName);
        //    if (bChanged == true)//日志文件名改变
        //    {
        //        ChangeTraceListener(ModuleName);
        //    }
        //    AssemblyName assemblyName = Assembly.GetCallingAssembly().GetName();
        //    msg = "【程序集名称：" + assemblyName.Name + "】,【版本号：" + assemblyName.Version + "】。【信息：" + (string)msg + "】";
        //    Microsoft.Practices.EnterpriseLibrary.Logging.Logger.Write(msg, ModuleName, prop);
        //}

        //public static void Write(string ModuleName, object msg)
        //{
        //    if (m_bLogFlag == false)
        //        return;
        //    bool bChanged = CheckLogChanged(ModuleName);
        //    if (bChanged == true)//日志文件名改变
        //    {
        //        ChangeTraceListener(ModuleName);
        //    }
        //    AssemblyName assemblyName = Assembly.GetCallingAssembly().GetName();
        //    msg = "【程序集名称：" + assemblyName.Name + "】,【版本号：" + assemblyName.Version + "】。【信息：" + (string)msg + "】";
        //    Microsoft.Practices.EnterpriseLibrary.Logging.Logger.Write(msg, ModuleName);
        //}

        //public static void Write(object msg)
        //{
        //    if (m_bLogFlag == false)
        //        return;
        //    bool bChanged = CheckLogChanged("General");
        //    if (bChanged == true)//日志文件名改变
        //    {
        //        ChangeTraceListener("General");
        //    }
        //    AssemblyName assemblyName = Assembly.GetCallingAssembly().GetName();
        //    msg = "【程序集名称：" + assemblyName.Name + "】,【版本号：" + assemblyName.Version + "】。【信息：" + (string)msg + "】";
        //    Microsoft.Practices.EnterpriseLibrary.Logging.Logger.Write(msg, "General");
        //}
        //#endregion

        //public static void StopLog()
        //{
        //    try
        //    {
        //        m_bLogFlag = false;
        //        Microsoft.Practices.EnterpriseLibrary.Logging.Logger.Writer.Dispose();
        //    }
        //    catch (Exception)
        //    {
        //    }
        //}

        //public static void StartLog()
        //{
        //    try
        //    {
        //        LogArray.Clear();
        //        m_bLogFlag = true;
        //    }
        //    catch (Exception)
        //    {
        //    }
        //}

        //#region//改变日志监听文件名称
        //private static void ChangeTraceListener(string ModuleName)
        //{
        //    if (m_bLogFlag == false)
        //        return;
        //    try
        //    {
        //        IDictionary<string, LogSource> dic = Microsoft.Practices.EnterpriseLibrary.Logging.Logger.Writer.TraceSources;
        //        if (dic.Keys.Contains(ModuleName) == true)
        //        {
        //            IList<TraceListener> ls = dic[ModuleName].Listeners;
        //            if (ls.Count > 0)
        //            {
        //                TraceListenerWrapper Listener = (TraceListenerWrapper)ls[0];
        //                FlatFileTraceListener fileListener = (FlatFileTraceListener)Listener.InnerTraceListener;
        //                if (fileListener == null)
        //                    return;
        //                if (LogArray.ContainsKey(ModuleName) == false)
        //                {
        //                    string strMonth = System.DateTime.Now.ToString("yyyy-MM");
        //                    string strTime = System.DateTime.Now.ToString("yyyy-MM-dd");
        //                    string path = System.AppDomain.CurrentDomain.BaseDirectory;
        //                    LogArray.Add(ModuleName, path + "Log\\" + strMonth + "\\" + ModuleName + strTime + ".log");
        //                }
        //                StreamWriter wrt = null;
        //                string strLogFile = LogArray[ModuleName];
        //                if (File.Exists(strLogFile) == false)
        //                    wrt = File.CreateText(strLogFile);
        //                else
        //                    wrt = new StreamWriter(strLogFile, true);
        //                fileListener.Writer = wrt;
        //                LogArray[ModuleName] = strLogFile;
        //            }
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        Microsoft.Practices.EnterpriseLibrary.Logging.Logger.Write(ex.Message, "General");
        //    }
        ////}
        //#endregion
        #endregion



        private static NLog.Logger _loger = null;
        /// <summary>
        /// 程序集名称
        /// </summary>
        public static string AssemblyName { get; set; }

        static Logger()
        {
            //注册自定义Layout
            ConfigurationItemFactory.Default.LayoutRenderers
                .RegisterDefinition("CustomLayout", typeof(CustomLayoutLayoutRenderer));
        }

        /// <summary>
        /// 设置线程会话活动Id
        /// </summary>
        public static void SetActivityId(string activityId = null)
        {
            Trace.CorrelationManager.ActivityId = string.IsNullOrEmpty(activityId) ? Guid.NewGuid() : new Guid(activityId);
        }

        private static NLog.Logger GetCurProLoger(string moduleName)
        {
            SetActivityId();
            return _loger = NLog.LogManager.GetLogger(moduleName);
        }

        /// <summary>
        /// 兼容以前的老版本日志打印系统（Fatal:代码异常）
        /// </summary>
        /// <param name="ModuleName">自定义日志文件名称</param>
        /// <param name="message">错误信息</param>
        public static void Write(string moduleName, object message)
        {
            _loger = GetCurProLoger(moduleName);
            AssemblyName assemblyName = Assembly.GetCallingAssembly().GetName();
            message = "【程序集名称：" + assemblyName.Name + "】,【版本号：" + assemblyName.Version + "】。\r\n【信息：" + (string)message + "】";
            _loger.Fatal(message);
        }

        /// <summary>
        /// 兼容以前的老版本日志打印系统（Fatal:代码异常）
        /// </summary>
        /// <param name="msg"></param>
        public static void Write(object message)
        {
            AssemblyName assemblyName = Assembly.GetCallingAssembly().GetName();
            _loger = GetCurProLoger(assemblyName.Name);
            message = "【程序集名称：" + assemblyName.Name + "】,【版本号：" + assemblyName.Version + "】。\r\n【信息：" + (string)message + "】";
            _loger.Fatal(message);
        }


        /// <summary>
        /// 调试跟踪信息日志
        /// </summary>
        /// <param name="moduleName">自定义日志文件名称</param>
        /// <param name="message">错误信息</param>
        public static void Info(string moduleName, object message)
        { 
            _loger = GetCurProLoger(moduleName);
            AssemblyName assemblyName = Assembly.GetCallingAssembly().GetName();
            message = "【程序集名称：" + assemblyName.Name + "】,【版本号：" + assemblyName.Version + "】。\r\n【信息：" + (string)message + "】";
            _loger.Info(message.ToString());
        }

        /// <summary>
        /// 调试跟踪信息日志
        /// </summary>
        /// <param name="message">错误信息</param>
        public static void Info(object message)
        {
            AssemblyName assemblyName = Assembly.GetCallingAssembly().GetName();
            _loger = GetCurProLoger(assemblyName.Name);
            message = "【程序集名称：" + assemblyName.Name + "】,【版本号：" + assemblyName.Version + "】。\r\n【信息：" + (string)message + "】";
            _loger.Info(message.ToString());
        }

        /// <summary>
        /// 错误日志
        /// </summary>
        /// <param name="moduleName">自定义日志文件名称</param>
        /// <param name="message">错误信息</param>
        public static void Error(string moduleName, object message)
        {
            _loger = GetCurProLoger(moduleName);
            AssemblyName assemblyName = Assembly.GetCallingAssembly().GetName();
            message = "【程序集名称：" + assemblyName.Name + "】,【版本号：" + assemblyName.Version + "】。\r\n【信息：" + (string)message + "】";
            _loger.Error(message.ToString());
        }

        /// <summary>
        /// 业务逻辑错误日志
        /// </summary>
        /// <param name="message">错误信息</param>
        public static void Error(object message)
        {
            AssemblyName assemblyName = Assembly.GetCallingAssembly().GetName();
            _loger = GetCurProLoger(assemblyName.Name);
            message = "【程序集名称：" + assemblyName.Name + "】,【版本号：" + assemblyName.Version + "】。\r\n【信息：" + (string)message + "】";
            _loger.Error(message.ToString());
        }


        /// <summary>
        /// 致命日志
        /// </summary>
        /// <param name="moduleName">自定义日志文件按名称</param>
        /// <param name="message">错误信息</param>
        public static void Fatal(string moduleName , object message)
        {
            _loger = GetCurProLoger(moduleName);
            AssemblyName assemblyName = Assembly.GetCallingAssembly().GetName();
            message = "【程序集名称：" + assemblyName.Name + "】,【版本号：" + assemblyName.Version + "】。\r\n【信息：" + (string)message + "】";
            _loger.Fatal(message);
        }

        /// <summary>
        /// 致命日志
        /// </summary>
        /// <param name="message">错误信息</param>
        public static void Fatal(object message)
        {
            AssemblyName assemblyName = Assembly.GetCallingAssembly().GetName();
            _loger = GetCurProLoger(assemblyName.Name);
            message = "【程序集名称：" + assemblyName.Name + "】,【版本号：" + assemblyName.Version + "】。\r\n【信息：" + (string)message + "】";
            _loger.Fatal(message);
        }
    }
    /// <summary>
    /// 自定义Layout
    /// </summary>
    [LayoutRenderer("CustomLayout")]
    public class CustomLayoutLayoutRenderer : LayoutRenderer
    {
        protected override void Append(StringBuilder builder, LogEventInfo logEvent)
        {
            builder.Append(Logger.AssemblyName);
        }
    }
}
